package org.microframework.cloud.gateway.config;

import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;

import java.util.*;

/**
 * Sentinel 配置
 * 实现熔断限流功能
 */
@Slf4j
@Configuration
public class SentinelConfiguration {

    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public SentinelConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /**
     * 初始化限流规则
     */
//    @PostConstruct
//    public void initGatewayRules() {
//        // 初始化自定义API分组
//        // initCustomizedApis();
//        // 初始化网关限流规则
//        //initGatewayFlowRules();
//        // 设置限流异常处理器
//        initBlockHandler();
//        // 设置API文档路径白名单
//       // initApiDocsWhitelist();
//    }

    /**
     * 初始化自定义API分组
     */
//    private void initCustomizedApis() {
//        Set<ApiDefinition> definitions = new HashSet<>();
//        ApiDefinition api1 = new ApiDefinition("system_api")
//                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
//                    add(new ApiPathPredicateItem().setPattern("/system/**")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                }});
//        definitions.add(api1);
//        
//        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
//        log.info("自定义API分组加载完成: {}", definitions);
//    }

    /**
     * 初始化网关限流规则
     */
//    private void initGatewayFlowRules() {
//        Set<GatewayFlowRule> rules = new HashSet<>();
//        
//        // 针对路由ID的限流规则
//        rules.add(new GatewayFlowRule("micro-cloud-system")
//                .setCount(5)
//                .setIntervalSec(1)
//        );
//        
//        // 针对自定义API分组的限流规则
//        rules.add(new GatewayFlowRule("system_api")
//                .setCount(3)
//                .setIntervalSec(1)
//                .setParamItem(new GatewayParamFlowItem()
//                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
//                        .setFieldName("userId")
//                )
//        );
//        
//        // API文档路由的限流规则 - 设置极高的阈值，实际上不限流
//        rules.add(new GatewayFlowRule("swagger-docs-system")
//                .setCount(10000)
//                .setIntervalSec(1)
//        );
//        
//        // Swagger API定义的限流规则 - 设置极高的阈值，实际上不限流
//        rules.add(new GatewayFlowRule("swagger_api_docs")
//                .setCount(10000)
//                .setIntervalSec(1)
//        );
//        
//        GatewayRuleManager.loadRules(rules);
//        log.info("网关限流规则加载完成: {}", rules);
//    }

    /**
     * 限流异常处理器
     */
//    private void initBlockHandler() {
//        GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
//            @Override
//            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
//                Map<String, Object> response = new HashMap<>();
//                response.put("code", 429);
//                response.put("message", "请求过于频繁，请稍后再试");
//                response.put("success", false);
//                System.out.println("==========================================================dassd");
//                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
//                        .contentType(MediaType.APPLICATION_JSON)
//                        .body(BodyInserters.fromValue(response));
//            }
//        });
//    }

    /**
     * 设置API文档路径白名单，这些路径不受限流规则影响
     */
//    private void initApiDocsWhitelist() {
//        // 创建一个API定义集合
//        Set<ApiDefinition> definitions = new HashSet<>();
//        
//        // 添加Swagger文档路径定义
//        ApiDefinition swaggerApi = new ApiDefinition("swagger_api_docs")
//                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
//                    // 添加所有Swagger相关路径
//                    add(new ApiPathPredicateItem().setPattern("/*/v3/api-docs/**")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                    add(new ApiPathPredicateItem().setPattern("/*/swagger-ui/**")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                    add(new ApiPathPredicateItem().setPattern("/*/swagger-resources/**")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                    add(new ApiPathPredicateItem().setPattern("/*/doc.html")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                    add(new ApiPathPredicateItem().setPattern("/*/webjars/**")
//                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
//                }});
//        
//        definitions.add(swaggerApi);
//        
//        // 加载API定义
//        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
//        log.info("API文档白名单配置加载完成: {}", definitions);
//    }

    /**
     * 注册Sentinel异常处理器
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    /**
     * 注册Sentinel过滤器
     */
    @Bean
    @Order(-1)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }
} 